package com.mt.sdk.ble.base;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import com.mt.sdk.ble.MTBLEDevice;
import com.mt.sdk.ble.MTBLEManager;
import com.mt.sdk.ble.MTBLEManager.MTScanCallback;
import com.mt.sdk.ble.MTBLEManager.ScanMode;
import com.mt.sdk.ble.model.BLEBaseAction;
import com.mt.sdk.ble.model.BLEBaseAction.ActionStatues;
import com.mt.sdk.ble.model.ErroCode;
import com.mt.sdk.ble.model.ReadCharactAction;
import com.mt.sdk.ble.model.ReadDescriptorAction;
import com.mt.sdk.ble.model.ReadRssiAction;
import com.mt.sdk.ble.model.SendBigDatasAction;
import com.mt.sdk.ble.model.WriteCharactAction;
import com.mt.sdk.ble.model.WriteCharactWithAckAction;
import com.mt.sdk.ble.model.WriteDescriptorAction;
import com.mt.sdk.tools.MTTools;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Handler;

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class BLEBase {
	private static final int SLEEPTIME = 20;
	private Context context;
	private MTBLEManager manager;
	private BluetoothGatt mBluetoothGatt;
	private BluetoothDevice device;
	private Handler handl = new Handler();

	public BLEBase(Context context, MTBLEManager manager) {
		this.context = context;
		this.manager = manager;

		setBroadcast();
	}

	// 设置广播
	private BroadcastReceiver receiver;
	private IntentFilter filter;

	private void setBroadcast() {
		receiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				String action = intent.getAction();
				if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { // 监听蓝牙开关变化
					int statues = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF);
					if(statues == BluetoothAdapter.STATE_ON){
						if (worktype == WORKTYPE.scanning) { // 还处于扫描状态的情况
							longScanBLEWithRssi(ScanMode.FAST, needrssi);
						}
					}else if(statues == BluetoothAdapter.STATE_OFF){
						if (worktype == WORKTYPE.scanning) { // 还处于扫描状态的情况
							handl.removeCallbacks(scanLoopStart); // 移除循环扫描事件
							handl.removeCallbacks(scanLoopStop); // 移除循环扫描事件
							handl.removeCallbacks(fastScanRunnable);
							handl.removeCallbacks(lowpowerScanRunnable);
							onBaseConnect(ErroCode.ERROMAP.get("bleunable"));
							return;
						}
						
						if(worktype == WORKTYPE.connectting){
							onBaseConnect(ErroCode.ERROMAP.get("bleunable"));
							if(mBluetoothGatt != null){
								mBluetoothGatt.close();
							}
							return;
						}
					}
					return;
				}
			}
		};

		filter = new IntentFilter();
		filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
		context.registerReceiver(receiver, filter);
	}

	// 连接
	private String connectMac;
	private int usersetconnectRetryTimes;
	private int connectRetryTimes;

	public ErroCode connect(String mac, int retryTimes, boolean isScan) {
		MTTools.logout("connect->" + mac);
		if (!manager.mBluetoothAdapter.isEnabled()) {
			return ErroCode.ERROMAP.get("bleunable"); // 没有开启蓝牙
		}

		// 判断是否有任务已经启动了连接
		if (worktype != WORKTYPE.free) {
			return ErroCode.ERROMAP.get("busy"); // 忙状态
		}

		// 检查mac是否有错误
		try {
			device = manager.mBluetoothAdapter.getRemoteDevice(mac);
		} catch (Exception e) {
			return ErroCode.ERROMAP.get("macerro"); // mac有错误
		}
		if (device == null) {
			return ErroCode.ERROMAP.get("macerro"); // mac有错误
		}

		this.connectMac = mac; // 保存设置的连接参数
		this.usersetconnectRetryTimes = retryTimes;
		this.connectRetryTimes = this.usersetconnectRetryTimes;

		if (isScan) { // 先扫描再进行连接
			scanBLE();
		} else {
			__connect();
		}

		return ErroCode.ERROMAP.get("OK");
	}

	// 带信号强度的连接会一直等待,直到搜索到信号或者连接失败才会回调
	private int needrssi = 0;

	public ErroCode connectWithRssi(String mac, int retryTimes, int rssi) {

		MTTools.logout("connectWithRssi->" + mac + ",  rssi->" + rssi);
		if (!manager.mBluetoothAdapter.isEnabled()) {
			return ErroCode.ERROMAP.get("bleunable"); // 没有开启蓝牙
		}

		// 判断是否有任务已经启动了连接
		if (worktype != WORKTYPE.free) {
			return ErroCode.ERROMAP.get("busy"); // 忙状态
		}

		// 检查mac是否有错误
		try {
			device = manager.mBluetoothAdapter.getRemoteDevice(mac);
		} catch (Exception e) {
			return ErroCode.ERROMAP.get("macerro"); // mac有错误
		}
		if (device == null) {
			return ErroCode.ERROMAP.get("macerro"); // mac有错误
		}

		this.needrssi = rssi; // 保存设置的连接参数
		this.connectMac = mac;
		this.usersetconnectRetryTimes = retryTimes;
		this.connectRetryTimes = this.usersetconnectRetryTimes;

		worktype = WORKTYPE.scanning;
		longScanBLEWithRssi(ScanMode.FAST, needrssi); // 首次扫描采用高速

		return ErroCode.ERROMAP.get("OK");
	}

	private MTScanCallback scanCallbackWithRssi = new MTScanCallback() {

		@Override
		public void onScanFail(int errocode, String erromsg) {

		}

		@Override
		public void onScan(MTBLEDevice device) {
			if (worktype != WORKTYPE.scanning) { // 非扫描状态，不需要理会
				return;
			}
			if (!device.getDevice().getAddress().equals(connectMac)) { // 不是这个mac
				return;
			}
			System.out.println("找到目标设备->" + device.getDevice().getAddress());
			scanfind_flag = true;
			if (device.getCurrentRssi() < needrssi) { // 扫描到，但是信号强度太弱,就马上切换到快速扫描模式
				System.out.println("目标设备距离太远->" + device.getCurrentRssi());
				return;
			}
			System.out.println("寻找目标设备成功");
			worktype = WORKTYPE.free; // 扫描到了结果
			handl.removeCallbacks(scanLoopStart); // 移除循环扫描事件
			handl.removeCallbacks(scanLoopStop); // 移除循环扫描事件
			handl.removeCallbacks(fastScanRunnable);
			handl.removeCallbacks(lowpowerScanRunnable);
			manager.stopScan();
			connect(connectMac, usersetconnectRetryTimes, false);
		}

		@Override
		public void onScanOver(ErroCode errocode) {
			
		}
	};
	private boolean scanfind_flag = false;
	private Runnable fastScanRunnable = new Runnable() {

		@Override
		public void run() {
			longScanBLEWithRssi(ScanMode.FAST, needrssi);
		}
	};
	private Runnable lowpowerScanRunnable = new Runnable() {

		@Override
		public void run() {
			longScanBLEWithRssi(ScanMode.LOWPOWER, needrssi);
		}
	};
	private Runnable scanLoopStop = new Runnable() {

		@Override
		public void run() {
			if (worktype != WORKTYPE.scanning) { // 非扫描状态，不需要理会
				return;
			}
			manager.stopScan();
			handl.postDelayed(scanLoopStart, 1000); // 停止扫描1秒后，开始扫描
		}
	};
	private Runnable scanLoopStart = new Runnable() {

		@Override
		public void run() {
			if (worktype != WORKTYPE.scanning) { // 非扫描状态，不需要理会
				return;
			}
			if (scanfind_flag) {
				handl.post(fastScanRunnable);
			} else {
				handl.post(lowpowerScanRunnable);
			}
		}
	};

	// 断开连接
	public boolean disConnect() {
		System.out.println("disConnect");

		if (worktype == WORKTYPE.scanning) { // 如果还在扫描的情况
			worktype = WORKTYPE.free;
			manager.stopScan();
			handl.removeCallbacks(scanTimeoutRunnable);
			handl.removeCallbacks(scanLoopStart);
			handl.removeCallbacks(scanLoopStop);
			handl.removeCallbacks(fastScanRunnable);
			handl.removeCallbacks(lowpowerScanRunnable);
			return true;
		}

		// 删除所有任务
		for (BLEBaseAction BLEBaseAction2 : taskList) {
			BLEBaseAction2.onCancel();
		}
		taskList.clear();

		if (!isConnected()) {
			worktype = WORKTYPE.free;
			if (mBluetoothGatt != null) {
				mBluetoothGatt.close();
				mBluetoothGatt = null;
			}
			return true;
		}

		if (mBluetoothGatt != null) {
			worktype = WORKTYPE.disconnectting;
			mBluetoothGatt.disconnect();
			return true;
		}
		return false;
	}

	// 扫描
	private ErroCode scanBLE() {
		worktype = WORKTYPE.scanning; // 处于扫描状态
		handl.postDelayed(scanTimeoutRunnable, 5000); // 5秒没有搜索到，则认为不正常
		manager.startScan(ScanMode.FAST, null,new MTScanCallback() {

			@Override
			public void onScanFail(int errocode, String erromsg) {
				worktype = WORKTYPE.free;
				handl.removeCallbacks(scanTimeoutRunnable); // 移除连接超时
				onBaseConnect(ErroCode.ERROMAP.get("scanerro"));
			}

			@Override
			public void onScan(MTBLEDevice scandevice) {
				if ((scandevice == null) || (scandevice.getDevice().getAddress() == null)) {
					return;
				}
				if (scandevice.getDevice().getAddress().equals(connectMac)) {
					manager.stopScan();
					handl.removeCallbacks(scanTimeoutRunnable); // 移除连接超时
					__connect();
					return;
				}
			}

			@Override
			public void onScanOver(ErroCode errocode) {
				
			}
		},5, 1, 0);

		return ErroCode.ERROMAP.get("OK");
	}

	private ErroCode longScanBLEWithRssi(ScanMode scanmode, int rssi) {
		if (!manager.isEnable()) {
			return ErroCode.ERROMAP.get("bleunable");
		}
		if (worktype != WORKTYPE.scanning) { // 不处于扫描模式下
			return ErroCode.ERROMAP.get("busy");
		}
		if (scanmode == ScanMode.LOWPOWER) {
			System.out.println("使用低速扫描");
		} else {
			System.out.println("使用高速扫描");
		}

		scanfind_flag = false;
		manager.startScan(scanmode, null, scanCallbackWithRssi, 10, 1, 0);
		handl.postDelayed(scanLoopStop, 5000); // 扫描5秒作为一个周期
		return ErroCode.ERROMAP.get("OK");
	}

	// 连接
	private ErroCode __connect() {

		System.out.println("connectRetryTimes->" + connectRetryTimes);
		if (connectRetryTimes < 0) {
			worktype = WORKTYPE.free;
			onBaseConnect(ErroCode.ERROMAP.get("timeout"));
			return ErroCode.ERROMAP.get("OK");
		}

		if (this.connectRetryTimes != this.usersetconnectRetryTimes) { // 不是第一次就是重试
			reTryConnect(this.connectRetryTimes);
		}

		worktype = WORKTYPE.connectting;
//		manager.stopScan(); // 停止扫描
		manager.pauseScan(true);

		connectRetryTimes--;

		if (mBluetoothGatt != null) {
			mBluetoothGatt.close();
		}
		mBluetoothGatt = device.connectGatt(context, false, mGattCallback);

		return ErroCode.ERROMAP.get("OK");
	}

	// private boolean lastconnectstatues = false;
	private long lastconnecterro_time = 0;
	private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {

		@Override
		public void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) {
			super.onConnectionStateChange(gatt, status, newState);
			System.out.println("onBaseConnectionStateChange->" + status + ", " + newState);

			if ((status == 133) && (newState == BluetoothProfile.STATE_DISCONNECTED) && (manager.isEnable())) { // 断开出错的情况
				System.out.println("出现133错误");
				if ((System.currentTimeMillis() - lastconnecterro_time) < 500) { // 500ms内如果出现2次133错误，则自动重启一下蓝牙
					System.out.println("出错了需要重连------------------------------------");
					manager.enable(false); // 强制关闭蓝牙，并且3秒后重启
					handl.postDelayed(new Runnable() {

						@Override
						public void run() {
							if (!manager.isEnable()) {
								manager.enable(true);
							}
						}
					}, 3000);
				}
				lastconnecterro_time = System.currentTimeMillis();
			}
			handl.post(new Runnable() {
				@Override
				public void run() {
					removeListCharact();
					if (newState == BluetoothProfile.STATE_DISCONNECTED) { // 如果是断开
						
						// 清理所有任务
						for (BLEBaseAction BLEBaseAction2 : taskList) {
							if(BLEBaseAction2.getStatues() != BLEBaseAction.ActionStatues.DONE){
								BLEBaseAction2.onFail(ErroCode.ERROMAP.get("unconnect"));
							}
						}
						taskList.clear();
						
						if (worktype == WORKTYPE.connectting) { // 连接时断开，则重连
							handl.removeCallbacks(waitStableRunnable); // 移除等待稳定超时
							__connect();
						} else if (worktype == WORKTYPE.disconnectting) { // 如果是主动断开
							if (status != BluetoothGatt.GATT_SUCCESS) { // 断开失败
								if(isConnected()){
									System.out.println("断开失败");
									onManualDisConnect(ErroCode.ERROMAP.get("unforturedis"));
								}else{
									worktype = WORKTYPE.free;
									gatt.close();
									onManualDisConnect(ErroCode.ERROMAP.get("OK"));
								}
							} else {
								worktype = WORKTYPE.free;
								gatt.close();
								onManualDisConnect(ErroCode.ERROMAP.get("OK"));
							}
						} else { // 意外断开
							gatt.close();
							onDisConnect(ErroCode.ERROMAP.get("OK"));
						}
					} else { // 如果是连接

						if (gatt.getDevice() != device) { // 如果不是本设备
							gatt.disconnect();
							return;
						}
						mBluetoothGatt = gatt;

						if (worktype == WORKTYPE.free) { // 不做任何反馈
							mBluetoothGatt.disconnect();
							System.out.println("过时的连接操作");
							return;
						}

						if (status != BluetoothGatt.GATT_SUCCESS) { // 连接失败,重连
							if (worktype == WORKTYPE.connectting) {
								System.out.println("连接失败,重连");
								__connect();
							}
						} else { // 连接成功
							mBluetoothGatt.discoverServices(); // 发现服务
						}
					}
				}
			});
		}

		@Override
		public void onServicesDiscovered(BluetoothGatt gatt, final int status) {
			super.onServicesDiscovered(gatt, status);
			System.out.println("onServicesDiscovered->" + status);
			handl.post(new Runnable() {
				@Override
				public void run() {
					if (status != BluetoothGatt.GATT_SUCCESS) { // 获取服务失败,重连
						if (worktype == WORKTYPE.connectting) {
							System.out.println("获取服务失败,重连");
							mBluetoothGatt.disconnect(); // 如果发现服务失败，则直接产生个意外断开事件
						}
					} else {
						handl.postDelayed(waitStableRunnable, 1000); // 等待1秒稳定连接
					}
				}
			});
		}

		@Override
		public void onDescriptorWrite(BluetoothGatt gatt, final BluetoothGattDescriptor descriptor, final int status) {
			super.onDescriptorWrite(gatt, descriptor, status);
			System.out.println("onDescriptorWrite->" + status);
			handl.post(new Runnable() {
				@Override
				public void run() {
					if (taskList.size() == 0) {
						return;
					}
					BLEBaseAction task2 = taskList.get(0);
					if ((task2.getActiontype() != BLEBaseAction.ActionType.WRITEDESCRIPTOR)) {
						return;
					}
					WriteDescriptorAction task = (WriteDescriptorAction) task2;
					if ((task == null) || (task.getDescriptor() != descriptor)) { // 不是此任务
						return;
					}

					task.setStatues(ActionStatues.DONE);
					goonTask(); // 继续任务
					if (status != BluetoothGatt.GATT_SUCCESS) { // 设置可通知失败
						task.onFail(ErroCode.ERROMAP.get("unknow"));
					} else {
						task.onSuccess();
					}
				}
			});
		}

		@Override
		public void onCharacteristicWrite(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic,
				final int status) {
			System.out.println("onCharacteristicWrite->" + status);
			super.onCharacteristicWrite(gatt, characteristic, status);
			handl.post(new Runnable() {

				@Override
				public void run() {
					if (taskList.size() == 0) {
						return;
					}
					BLEBaseAction task2 = taskList.get(0);
					if (task2.getActiontype() == BLEBaseAction.ActionType.SENDBIGDATAS) { // 发送大数据时，不需要做任何响应
						return;
					}
					if ((task2.getActiontype() != BLEBaseAction.ActionType.WRITECHACT)
							&& (task2.getActiontype() != BLEBaseAction.ActionType.WRITECHACTWITHACK)) {
						return;
					}
					// WriteCharactAction task = (WriteCharactAction) task2;
					BluetoothGattCharacteristic charact;

					if (task2.getActiontype() == BLEBaseAction.ActionType.WRITECHACT) {
						charact = ((WriteCharactAction) task2).getCharact();
					} else {
						charact = ((WriteCharactWithAckAction) task2).getSendCharact();
					}

					if (charact != characteristic) { // 不是此任务
						return;
					}
					if (status != BluetoothGatt.GATT_SUCCESS) { // 设置可通知失败
						task2.setStatues(ActionStatues.DONE);
						task2.onFail(ErroCode.ERROMAP.get("unknow"));
					}

					int deleytime = 0; // 需要的延迟
					if (0 != (charact.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) {
						deleytime = SLEEPTIME;
					}
					handl.postDelayed(new Runnable() {
						public void run() {
							goonTask(); // 继续任务
						}
					}, deleytime);
				}
			});
		}

		@Override
		public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
				final int status) {
			super.onCharacteristicRead(gatt, characteristic, status);
			final BluetoothGattCharacteristic charact = characteristic;
			final byte[] datas = new byte[characteristic.getValue().length];
			MTTools.arraycopy(characteristic.getValue(), 0, datas, 0, datas.length);
			handl.post(new Runnable() {

				@Override
				public void run() {
					if (taskList.size() == 0) {
						return;
					}
					BLEBaseAction task2 = taskList.get(0);
					if ((task2.getActiontype() != BLEBaseAction.ActionType.READCHACT)) {
						return;
					}
					ReadCharactAction task = (ReadCharactAction) task2;
					if ((task == null) || (task.getCharact() != charact)) { // 不是此任务
						return;
					}

					task.setStatues(ActionStatues.DONE);
					goonTask(); // 继续任务
					if (status != BluetoothGatt.GATT_SUCCESS) { // 设置可通知失败
						task.onFail(ErroCode.ERROMAP.get("unknow"));
					} else {
						task.onReadDatas(charact, datas);
					}
				}
			});
		}

		@Override
		public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
			System.out
					.println("onCharacteristicChanged->" + MTTools.convertBytearrayToString(characteristic.getValue()));
			super.onCharacteristicChanged(gatt, characteristic);
			final BluetoothGattCharacteristic charact = characteristic;
			final byte[] datas = new byte[characteristic.getValue().length];
			MTTools.arraycopy(characteristic.getValue(), 0, datas, 0, datas.length);
			handl.post(new Runnable() {
				public void run() {

					if (taskList.size() != 0) {
						BLEBaseAction task2 = taskList.get(0);
						if (task2.getActiontype() == BLEBaseAction.ActionType.WRITECHACTWITHACK) {
							WriteCharactWithAckAction task = (WriteCharactWithAckAction) task2;
							if (task.getReviceCharact() == charact) { // 不是此任务
								task.onReciveDatas(charact, datas);
								if (task.getStatues() == ActionStatues.DONE) {
									goonTask();
								}
								return;
							}
						}

						if (task2.getActiontype() == BLEBaseAction.ActionType.SENDBIGDATAS) {
							SendBigDatasAction task = (SendBigDatasAction) task2;
							if((charact != task.getReviceCharact()) || (datas.length != 2)){
								return;
							}
							if((task.getSendingIndex()-1) != (MTTools.convertUint16(datas[0], datas[1]))){
								task.setStatues(ActionStatues.DONE);
								task.onFail(ErroCode.ERROMAP.get("lostdatas"));
							}
							goonTask();
							return;
						}

					}
					for (BluetoothGattCharacteristic bluetoothGattCharacteristic : listenedCharacts) {
						if (charact == bluetoothGattCharacteristic) { // 在被监听列表
							onCharactChanged(charact, datas);
						}
					}
				}
			});
		}

		@Override
		public void onDescriptorRead(BluetoothGatt gatt, final BluetoothGattDescriptor descriptor, final int status) {
			System.out.println("onDescriptorRead->" + status);
			super.onDescriptorRead(gatt, descriptor, status);
			handl.post(new Runnable() {

				@Override
				public void run() {
					if (taskList.size() == 0) {
						return;
					}
					BLEBaseAction task2 = taskList.get(0);
					if ((task2.getActiontype() != BLEBaseAction.ActionType.READDESCRIPTOR)) {
						return;
					}
					ReadDescriptorAction task = (ReadDescriptorAction) task2;
					if ((task == null) || (task.getDescriptor() != descriptor)) { // 不是此任务
						return;
					}

					task.setStatues(ActionStatues.DONE);
					goonTask(); // 继续任务
					if (status != BluetoothGatt.GATT_SUCCESS) { // 设置可通知失败
						task.onFail(ErroCode.ERROMAP.get("unknow"));
					} else {
						task.onSuccess();
					}
				}
			});
		}

		@Override
		public void onReadRemoteRssi(BluetoothGatt gatt, final int rssi, final int status) {
			super.onReadRemoteRssi(gatt, rssi, status);
			System.out.println("onReadRemoteRssi->" + status);
			handl.post(new Runnable() {
				@Override
				public void run() {
					if (taskList.size() == 0) {
						return;
					}
					BLEBaseAction task2 = taskList.get(0);
					if ((task2.getActiontype() != BLEBaseAction.ActionType.READRSSI)) {
						return;
					}
					ReadRssiAction task = (ReadRssiAction) task2;

					task.setStatues(ActionStatues.DONE);
					goonTask(); // 继续任务
					if (status != BluetoothGatt.GATT_SUCCESS) {
						task.onFail(ErroCode.ERROMAP.get("unknow"));
					} else {
						task.onSuccess(rssi);
					}
				}
			});
		}

	};

	// 连接超时处理
	private Runnable scanTimeoutRunnable = new Runnable() {
		@Override
		public void run() {
			worktype = WORKTYPE.free;
			manager.stopScan();
			onBaseConnect(ErroCode.ERROMAP.get("cantfinddevice"));
		}
	};

	// 等待连接稳定
	private Runnable waitStableRunnable = new Runnable() {
		public void run() {
			if (worktype != WORKTYPE.connectting) {
				return;
			}
			if (!isConnected()) {
				__connect();// 尝试重连
				return;
			}
			worktype = WORKTYPE.free;
			goonTask(); // 连接成功，则开始执行发送任务
			onBaseConnect(ErroCode.ERROMAP.get("OK"));// 连接成功
			return;
		}
	};

	// 查看连接状态
	public boolean isConnected() {
		if (device == null) {
			return false;
		}
		if (manager.mBluetoothManager.getConnectionState(device,
				BluetoothProfile.GATT) == BluetoothProfile.STATE_CONNECTED) {
			return true;
		} else {
			return false;
		}
	}

	// 获取所有services
	public List<BluetoothGattService> getAllServices() {
		return mBluetoothGatt.getServices();
	}

	// 获取某个特定的service
	public BluetoothGattService getService(String uuid) {
		return mBluetoothGatt.getService(UUID.fromString(uuid));
	}

	// 获取某个特定的特征值
	public BluetoothGattCharacteristic getCharact(String serviceuuid, String charactuuid) {
		BluetoothGattService service = getService(serviceuuid);
		if (service == null) {
			return null;
		}
		return service.getCharacteristic(UUID.fromString(charactuuid));
	}

	// 使能接收notify
	public boolean enableNotify(BluetoothGattCharacteristic characteristic, boolean enable) {
		return mBluetoothGatt.setCharacteristicNotification(characteristic, enable);
	}

	// 任务列表
	private boolean setRunFlag = true; // 任务是否运行标志
	private boolean isRunning = false; // 任务运行状态
	private List<BLEBaseAction> taskList = new ArrayList<BLEBaseAction>();

	public ErroCode addNewAction(BLEBaseAction action) {

		if (!isConnected()) { // 没有连接的情况
			return ErroCode.ERROMAP.get("unconnect");
		}

		if (action == null) { // 参数不为空
			return ErroCode.ERROMAP.get("null");
		}

		taskList.add(action);

		if (!isRunning) { // 如果没有开始跑任务，则开始运行
			goonTask();
		}

		return ErroCode.ERROMAP.get("OK");
	}

	// 暂停任务
	public void stop() {
		this.setRunFlag = false;
	}

	// 开始任务
	public void start() {
		if (this.setRunFlag) {
			return;
		}
		this.setRunFlag = true;
		goonTask();
	}

	// 继续运行任务
	private void goonTask() {
		handl.removeCallbacks(tasktimeoutRunnable);
		isRunning = true;

		// System.out.println("taskList.size()->" + taskList.size());
		if (!setRunFlag) { // 如果用户设置了停止任务运行
			isRunning = false;
			return;
		}

		if (taskList.size() == 0) { // 没有任务需要运行
			isRunning = false;
			return;
		}

		if (!isConnected()) { // 如果失去连接
			isRunning = false;
			return;
		}

		// 寻找可用任务
		for (int i = 0; i < taskList.size(); i++) {
			if (taskList.get(i).getStatues() == BLEBaseAction.ActionStatues.CANCEL) { // 如果该任务被取消，则从任务队伍里面删除掉
				taskList.remove(i);
				i--;
				continue;
			}

			if (taskList.get(i).getStatues() == BLEBaseAction.ActionStatues.DONE) { // 如果该任务完成，则从任务队伍里面删除掉
				taskList.remove(i);
				i--;
				continue;
			}
		}
		if (taskList.size() == 0) { // 没有任务了
			isRunning = false;
			return;
		}

		BLEBaseAction task = taskList.get(0); // 获取需要执行的任务
		// 读特征值任务
		if (task.getActiontype() == BLEBaseAction.ActionType.READCHACT) {
			task.setStatues(BLEBaseAction.ActionStatues.RUNING); // 设置成正在运行
			handl.postDelayed(tasktimeoutRunnable, task.getOption().getTimeout());
			task.onStart(); // 提示开始任务
			if (!mBluetoothGatt.readCharacteristic(((ReadCharactAction) task).getCharact())) {
			}
			return;
		}

		// 写特征值任务
		if (task.getActiontype() == BLEBaseAction.ActionType.WRITECHACT) {
			handl.removeCallbacks(tasktimeoutRunnable);
			handl.postDelayed(tasktimeoutRunnable, task.getOption().getTimeout());
			if (task.getStatues() == BLEBaseAction.ActionStatues.WAITTING) {
				task.setStatues(BLEBaseAction.ActionStatues.RUNING);
				task.onStart();
			}
			final WriteCharactAction writetask = (WriteCharactAction) task;
			task.setStatues(BLEBaseAction.ActionStatues.RUNING);
			byte[] senddata = writetask.getPerdatas();

			if (senddata == null) { // 已经发送完毕这条数据
				writetask.setStatues(BLEBaseAction.ActionStatues.DONE);
				writetask.onSuccess();
				handl.post(new Runnable() { // 采用这种方式进行回调，从而防止出现递归
					public void run() {
						goonTask();
					}
				});
				return;
			}
			System.out.println("写特征值->"+MTTools.convertBytearrayToString(senddata));
			BluetoothGattCharacteristic charact = writetask.getCharact();
			charact.setValue(senddata);
			writetask.onSendDatas(senddata);
			if (!mBluetoothGatt.writeCharacteristic(charact)) { // 发送失败
			}
			return;
		}

		// 写descriptor
		if (task.getActiontype() == BLEBaseAction.ActionType.WRITEDESCRIPTOR) {
			handl.removeCallbacks(tasktimeoutRunnable);
			handl.postDelayed(tasktimeoutRunnable, task.getOption().getTimeout());
			task.setStatues(BLEBaseAction.ActionStatues.RUNING);
			if (task.getStatues() == BLEBaseAction.ActionStatues.WAITTING) {
				task.onStart();
			}

			BluetoothGattDescriptor descriptor = ((WriteDescriptorAction) task).getDescriptor();
			if (!mBluetoothGatt.writeDescriptor(descriptor)) { // 发送失败
			}
			return;
		}

		// 读descriptor通知
		if (task.getActiontype() == BLEBaseAction.ActionType.READDESCRIPTOR) {
			task.setStatues(BLEBaseAction.ActionStatues.RUNING); // 设置成正在运行
			handl.postDelayed(tasktimeoutRunnable, task.getOption().getTimeout());
			task.onStart(); // 提示开始任务
			if (!mBluetoothGatt.readDescriptor(((ReadDescriptorAction) task).getDescriptor())) {
			}
			return;
		}

		// 读取rssi
		if (task.getActiontype() == BLEBaseAction.ActionType.READRSSI) {
			task.setStatues(BLEBaseAction.ActionStatues.RUNING); // 设置成正在运行
			handl.postDelayed(tasktimeoutRunnable, task.getOption().getTimeout());
			task.onStart(); // 提示开始任务
			if (!mBluetoothGatt.readRemoteRssi()) {
			}
			return;
		}

		// 写有反馈特征值任务
		if (task.getActiontype() == BLEBaseAction.ActionType.WRITECHACTWITHACK) {
			handl.removeCallbacks(tasktimeoutRunnable);
			handl.postDelayed(tasktimeoutRunnable, task.getOption().getTimeout());
			if (task.getStatues() == BLEBaseAction.ActionStatues.WAITTING) {
				task.setStatues(BLEBaseAction.ActionStatues.RUNING);
				task.onStart();
			}
			final WriteCharactWithAckAction writetask = (WriteCharactWithAckAction) task;
			task.setStatues(BLEBaseAction.ActionStatues.RUNING);
			byte[] senddata = writetask.getPerdatas();

			if (senddata == null) { // 已经发送完毕这条数据,等待用户停止
				return;
			}

			BluetoothGattCharacteristic charact = writetask.getSendCharact();
			charact.setValue(senddata);
			writetask.onSendDatas(senddata);
			if (!mBluetoothGatt.writeCharacteristic(charact)) { // 发送失败
			}
			return;
		}

		// 写大数据任务
		if (task.getActiontype() == BLEBaseAction.ActionType.SENDBIGDATAS) {
			handl.removeCallbacks(tasktimeoutRunnable);
			handl.postDelayed(tasktimeoutRunnable, task.getOption().getTimeout());
			if (task.getStatues() == BLEBaseAction.ActionStatues.WAITTING) {
				task.setStatues(BLEBaseAction.ActionStatues.RUNING);
				task.onStart();
			}
			final SendBigDatasAction writetask = (SendBigDatasAction) task;
			task.setStatues(BLEBaseAction.ActionStatues.RUNING);
			byte[] senddata = writetask.getDatas();

			if (senddata == null) { // 已经发送完毕这条数据,等待用户停止
				writetask.setStatues(BLEBaseAction.ActionStatues.DONE);
				writetask.onSuccess();
				handl.post(new Runnable() { // 采用这种方式进行回调，从而防止出现递归
					public void run() {
						goonTask();
					}
				});
				return;
			}
			System.out.println("写入大数据->"+MTTools.convertBytearrayToString(senddata));
			BluetoothGattCharacteristic charact = writetask.getSendCharact();
			charact.setValue(senddata);
			writetask.onSendProcess(writetask.getSendingIndex() - 1);
			if (!mBluetoothGatt.writeCharacteristic(charact)) { // 发送失败
			}
			return;
		}

		// 没有定义的操作，则直接过滤掉
		task.setStatues(BLEBaseAction.ActionStatues.DONE);
		task.onCancel();
		handl.post(new Runnable() {
			public void run() {
				goonTask();
			}
		});
	}

	// 任务超时
	private Runnable tasktimeoutRunnable = new Runnable() {
		public void run() {
			if (taskList.size() == 0) {
				return;
			}
			BLEBaseAction task = taskList.get(0); // 获取需要执行的任务
			if (task.getStatues() != ActionStatues.RUNING) {
				return;
			}
			task.onFail(ErroCode.ERROMAP.get("timeout")); // 提示超时错误
			task.setStatues(ActionStatues.DONE);
			goonTask();
		}
	};

	// 连接回调
	protected void onBaseConnect(ErroCode errocode) {
		manager.pauseScan(false);
	}

	protected void reTryConnect(int lasttimes) {

	}

	protected void onDisConnect(ErroCode errocode) {

	}

	protected void onManualDisConnect(ErroCode errocode) {

	}

	protected void onCharactChanged(BluetoothGattCharacteristic characteristic, byte[] datas) {

	}

	// 添加被监听的特征值
	private List<BluetoothGattCharacteristic> listenedCharacts = new ArrayList<BluetoothGattCharacteristic>();

	public void addListCharact(BluetoothGattCharacteristic charact) {
		for (BluetoothGattCharacteristic bluetoothGattCharacteristic : listenedCharacts) {
			if (charact == bluetoothGattCharacteristic) { // 已经添加过了
				return;
			}
		}
		listenedCharacts.add(charact);
		mBluetoothGatt.setCharacteristicNotification(charact, true);
	}

	public void removeListCharact(BluetoothGattCharacteristic charact) {
		listenedCharacts.remove(charact);
		mBluetoothGatt.setCharacteristicNotification(charact, false);
	}

	// 删除所有监听列表
	private void removeListCharact() {
		listenedCharacts.clear();
	}

	// 清空缓存
	public boolean clearCache() {
		if (mBluetoothGatt == null) {
			return false;
		}

		try {
			Method localMethod = mBluetoothGatt.getClass().getMethod("refresh", new Class[0]);
			if (localMethod != null) {
				boolean result = ((Boolean) localMethod.invoke(mBluetoothGatt, new Class[0])).booleanValue();
				return result;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return true;
	}

	// 工作类型
	private WORKTYPE worktype = WORKTYPE.free;

	private enum WORKTYPE {
		free, scanning, disconnectting, connectting, sending
	}
}
